package net.beaconcontroller.comp416project.view;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import net.beaconcontroller.comp416project.controller.Controller;
import net.beaconcontroller.comp416project.model.HexIPString;

import org.openflow.protocol.OFFlowMod;
import org.openflow.protocol.OFMatch;
import org.openflow.protocol.action.OFAction;
import org.openflow.protocol.action.OFActionOutput;
/**
 * 
 * @author SHI ZHONGQI 10836265D from HK PolyU
 * @author JI ZHIHAO 13022865X from HK PolyU
 *
 */
public class FlowChangeView extends JFrame{
	private OFFlowMod fm;
	private static int id=0;
	private String name;
	private Controller controller;
	private boolean newFlow = false;
	private boolean port[]={false,false,false,false};
    private JButton jbt_Confirm;
    private JButton jbt_Cancel;
    private JButton jbt_Delete;

	private JCheckBox jcb_port1;
	private JCheckBox jcb_port2;
	private JCheckBox jcb_port3;
	private JCheckBox jcb_port4;
	
	private JTextField jtf_InPort;
	private JTextField jtf_dl_dst;
	private JTextField jtf_dl_src;
	private JTextField jtf_dl_type;
	private JTextField jtf_dl_vlan;
	private JTextField jtf_dl_vpcp;
	private JTextField jtf_nw_dst;
	private JTextField jtf_nw_src;
	private JTextField jtf_nw_proto;
	private JTextField jtf_nw_tos;
	private JTextField jtf_tp_dst;
	private JTextField jtf_tp_src;

	private JTextField jtf_idelTime;
	private JTextField jtf_hardTime;
	private JTextField jtf_priority;
	
	public FlowChangeView(OFFlowMod fm,Controller controller,String name){
		this.fm=fm;
		this.name=name;
		this.controller=controller;
		BuildUI();
	}
	public FlowChangeView(Controller controller){
		this.fm=new OFFlowMod();
		this.controller=controller;
		newFlow = true;
		BuildUI();
	}
	
	public boolean getNewFlow(){
		return newFlow;
	}
	
	private void BuildUI(){
		id++;
		JPanel container = new JPanel(new GridLayout(0,2));
		JPanel buttenContain = new JPanel(new GridLayout(0,3));

	 	jbt_Confirm=new JButton("Confirm");
	 	jbt_Confirm.setActionCommand("FCV_Confirm");
	 	jbt_Confirm.addActionListener(controller);
	 	jbt_Delete=new JButton("Delete");
	 	jbt_Delete.setActionCommand("FCV_Delete");
	 	jbt_Delete.addActionListener(controller);
	    jbt_Cancel=new JButton("Cancel");
	    jbt_Cancel.setActionCommand("FCV_Cancel");
	    jbt_Cancel.addActionListener(controller);
	    buttenContain.add(jbt_Confirm);
	    buttenContain.add(jbt_Cancel);
	    buttenContain.add(jbt_Delete);
	  
	    jbt_Delete.setEnabled(!newFlow);
	    
		jcb_port1=new JCheckBox();
		jcb_port2=new JCheckBox();
		jcb_port3=new JCheckBox();
		jcb_port4=new JCheckBox();
		
		jtf_InPort=new JTextField();
		jtf_dl_dst=new JTextField();
		jtf_dl_src=new JTextField();
		jtf_dl_type=new JTextField();
		jtf_dl_vlan=new JTextField();
		jtf_dl_vpcp=new JTextField();
		jtf_nw_dst=new JTextField();
		jtf_nw_src=new JTextField();
		jtf_nw_proto=new JTextField();
		jtf_nw_tos=new JTextField();
		jtf_tp_dst=new JTextField();
		jtf_tp_src=new JTextField();
		jtf_idelTime=new JTextField();
		jtf_hardTime=new JTextField();
		jtf_priority=new JTextField();
		if(!newFlow){
			OFMatch match = fm.getMatch();
			if(fm.getActions()!=null){		
			Iterator<OFAction> i = fm.getActions().iterator();
				while(i.hasNext()){
					port[(int)((OFActionOutput) i.next()).getPort()]=true;
				}
			}
			jtf_InPort.setText(""+match.getInputPort());
			jtf_dl_dst.setText(HexIPString.toHexString(match.getDataLayerDestination()));
			jtf_dl_src.setText(HexIPString.toHexString(match.getDataLayerSource()));
			jtf_dl_type.setText(""+match.getDataLayerType());
			jtf_dl_vlan.setText(""+match.getDataLayerVirtualLan());
			jtf_dl_vlan.setText(""+Byte.toString(match.getDataLayerVirtualLanPriorityCodePoint()));
			jtf_nw_dst.setText(HexIPString.toIp(match.getNetworkDestination(),match.getNetworkDestinationMaskLen()));
			jtf_nw_src.setText(HexIPString.toIp(match.getNetworkSource(),match.getNetworkSourceMaskLen()));
			jtf_nw_proto.setText(""+match.getNetworkProtocol());
			jtf_nw_tos.setText(""+match.getNetworkTypeOfService());
			jtf_tp_dst.setText(""+match.getTransportDestination());
			jtf_tp_src.setText(""+match.getTransportSource());
			jtf_idelTime.setText(""+fm.getIdleTimeout());
			jtf_hardTime.setText(""+fm.getHardTimeout());
			jtf_priority.setText(""+fm.getPriority());
		}
		container.add(new JLabel("In Port"));
		container.add(jtf_InPort);
		
		container.add(new JLabel("DL_DST"));
		container.add(jtf_dl_dst);
		
		container.add(new JLabel("DL_SRC"));
		container.add(jtf_dl_src);
		
		container.add(new JLabel("DL_TYPE"));
		container.add(jtf_dl_type);
		
		container.add(new JLabel("DL_VLAN"));
		container.add(jtf_dl_vlan);
		
		container.add(new JLabel("DL_VPCP"));
		container.add(jtf_dl_vpcp);
		
		container.add(new JLabel("NW_DST"));
		container.add(jtf_nw_dst);
		
		container.add(new JLabel("NW_SRC"));
		container.add(jtf_nw_src);
		
		container.add(new JLabel("NW_PROTO"));
		container.add(jtf_nw_proto);
		
		container.add(new JLabel("NW_TOS"));
		container.add(jtf_nw_tos);
		
		container.add(new JLabel("TP_DST"));
		container.add(jtf_tp_dst);
		
		container.add(new JLabel("TP_SRC"));
		container.add(jtf_tp_src);
		
		container.add(new JLabel("IdelTimeOut"));
		container.add(jtf_idelTime);
	
		container.add(new JLabel("HardTimeOut"));
		container.add(jtf_hardTime);
		
		container.add(new JLabel("Priority"));
		container.add(jtf_priority);
		
		container.add(new JLabel("OutPort 0"));
		container.add(jcb_port1);
		jcb_port1.setSelected(port[0]);
		container.add(new JLabel("OutPort 1"));
		container.add(jcb_port2);
		jcb_port2.setSelected(port[1]);
		container.add(new JLabel("OutPort 2"));
		container.add(jcb_port3);
		jcb_port3.setSelected(port[2]);
		container.add(new JLabel("OutPort 3"));
		container.add(jcb_port4);
		jcb_port4.setSelected(port[3]);

		setLayout(new BorderLayout());
		add(container,BorderLayout.CENTER);
		add(buttenContain,BorderLayout.SOUTH);
		
	}
	
	public OFFlowMod getTheFlowMod(){
		if(newFlow)
			fm.setMatch(new OFMatch());
		fm.getMatch().setInputPort(Short.parseShort(jtf_InPort.getText()));
		
		fm.getMatch().setDataLayerDestination(jtf_dl_dst.getText());
		fm.getMatch().setDataLayerSource(jtf_dl_src.getText());
		fm.getMatch().setDataLayerType(Short.parseShort(jtf_dl_type.getText()));
		fm.getMatch().setDataLayerVirtualLan(Short.parseShort(jtf_dl_vlan.getText()));
		//System.out.println(jtf_nw_dst.getText());
		fm.getMatch().setNetworkDestination(HexIPString.fromIPString(jtf_nw_dst.getText()));
		fm.getMatch().setNetworkSource(HexIPString.fromIPString(jtf_nw_src.getText()));
		fm.getMatch().setNetworkProtocol(Byte.parseByte(jtf_nw_proto.getText()));
		fm.getMatch().setNetworkTypeOfService(Byte.parseByte(jtf_nw_tos.getText()));
		fm.getMatch().setTransportDestination(Short.parseShort(jtf_tp_dst.getText()));
		fm.getMatch().setTransportSource(Short.parseShort(jtf_tp_src.getText()));
		
		fm.setIdleTimeout(Short.parseShort(jtf_idelTime.getText()));
		fm.setHardTimeout(Short.parseShort(jtf_hardTime.getText()));
		fm.setPriority(Short.parseShort(jtf_priority.getText()));
		
		 ArrayList<OFAction> list = new ArrayList<OFAction>();
		 if(jcb_port1.isSelected()){
			 OFAction action1 = new OFActionOutput((short) 0);
			 list.add(action1);
		 }
		 if(jcb_port2.isSelected()){
			 OFAction action2 = new OFActionOutput((short) 1);
			 list.add(action2);
		 }
		 if(jcb_port3.isSelected()){
			 OFAction action3 = new OFActionOutput((short) 2);
			 list.add(action3);
		 }
		 if(jcb_port4.isSelected()){
			 OFAction action4 = new OFActionOutput((short) 3);
			 list.add(action4);
		 }
		fm.setActions(list);
		return fm;
	}
	
	public String getName(){
		return name;
	}
	
	public int getID(){
		return id;
	}
}
